package com.example.demo.util;

public class PrimeGeneratorV4 {
    private static boolean[] f;
    private static boolean[] isCrossed;
    private static int[] result;
    private static int[] primes;
    private static int i;

    public static int[] generatePrimes(int maxValue){
        if (maxValue < 2){
            return new int[0];
        } else {
            initializeArrayOfIntegers(maxValue);
            crossOutMultiples();
            putUncrossedIntegerIntoResult();
            return result;
        }
    }

    private static void putUncrossedIntegerIntoResult(){
        result = new int[numberOfUncrossedIntegers()];
        for (int j = 0,i = 2; i < isCrossed.length; i++) {
            if (notCrossed(i)){
                result[j++] = i;
            }
        }
    }

    private static int numberOfUncrossedIntegers(){
        int count = 0;
        for (i = 2; i < isCrossed.length; i++) {
            if (notCrossed(i)){
                count++;
            }
        }
        return count;
    }

    private static void initializeArrayOfIntegers(int maxValue){
       isCrossed = new boolean[maxValue+1];
       for (i = 2;i < isCrossed.length;i++){
           isCrossed[i] = false;
       }
    }

    private static void crossOutMultiples(){
        int maxPrimeFactor = calcMaxPrimeFactor();
        for (i = 2;i <= maxPrimeFactor;i++){
            if (notCrossed(i)){
                crossOutMultiplesOf(i);
            }
        }
    }

    private static int calcMaxPrimeFactor(){
        Double maxPrimeFactor = Math.sqrt(isCrossed.length)+1;
        return Integer.parseInt(maxPrimeFactor.toString());
    }

    private static void crossOutMultiplesOf(int i){
        for (int multiple = 2 * i;multiple < isCrossed.length;multiple+=i){
            isCrossed[multiple] = true;
        }
    }

    private static boolean notCrossed(int i){
        return isCrossed[i] = false;
    }

    public static void main(String[] args) {
        int[] ints = generatePrimes(100);
        for (int anInt : ints) {
            System.out.println(anInt);
        }
        System.out.println("total:"+ints.length);
    }
}
